﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Murry.DataStore.MemoryDB
{
    /// <summary>
    /// IQueryable cloning wrapper class.
    /// </summary>
    /// <typeparam name="T">Type to clone.</typeparam>
    internal class CloningQueryable<T> : IQueryable<T>
    {
        /// <summary>
        /// Wrap and IQueryable.
        /// </summary>
        /// <param name="queryable"></param>
        public CloningQueryable(IQueryable<T> queryable)
        {
            Queryable = queryable;
        }

        /// <summary>
        /// The wrapped Queryable.
        /// </summary>
        private IQueryable<T> Queryable { get; set; }

        /// <summary>
        /// Pass through to Queryable.GetEnumerator()
        /// </summary>
        /// <returns>Enumerator</returns>
        public IEnumerator<T> GetEnumerator()
        {
            return Queryable.GetEnumerator();
        }

        /// <summary>
        /// Pass through to Queryable.GetEnumerator()
        /// </summary>
        /// <returns>Enumerator</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable)Queryable).GetEnumerator();
        }

        /// <summary>
        /// Pass through to Queryable.ElementType
        /// </summary>
        /// <returns>ElementType</returns>
        public Type ElementType
        {
            get { return Queryable.ElementType; }
        }

        /// <summary>
        /// Pass through to Queryable.Expression
        /// </summary>
        /// <returns>Expression</returns>
        public Expression Expression
        {
            get { return Queryable.Expression; }
        }

        /// <summary>
        /// Return Queryable's QueryProvider wrapped in a cloning QueryProvider
        /// </summary>
        public IQueryProvider Provider
        {
            get { return new CloningQueryProvider(Queryable.Provider); }
        }
    }
}
